package com.awesumgames.awesum;

import android.opengl.GLES20;
//import android.opengl.GLU;
import android.opengl.Matrix;
import static java.lang.Math.sin;
import static java.lang.Math.cos;
import static java.lang.Math.atan2;
import static java.lang.Math.sqrt;

import com.awesumgames.awesum.AwesumGlobal.Awesum.*;
import com.awesumgames.awesum.AwesumGlobal.Awesum;
import com.awesumgames.awesum.Vector3;

public class Camera {
	private static final float MOVE_RATIO = .9f;
	private static final Vector3 SHAKE_PYR_LIMIT = new Vector3(1f, 2f, 1f);
	private static final Vector3 defaultUp = new Vector3(0f, 1f, 0f);
	
	public Vector3 pos = new Vector3(), view = new Vector3(), up = defaultUp.copy();
	private boolean shake = false;
	
	public Camera() {
	}
	
	public void set(Vector3 newPos, Vector3 newView) {
		pos		= newPos.copy();
		view	= newView.copy();
	}
	public void set(Vector3 newPos, Vector3 newView, Vector3 newUp) {
		pos		= newPos.copy();
		view	= newView.copy();
		up		= newUp.copy();
	}
	public void set(float posX, float posY, float posZ, float viewX, float viewY, float viewZ) {
		pos.set(	posX,	posY,	posZ);
		view.set(	viewX,	viewY,	viewZ);
	}
	public void set(float posX, float posY, float posZ, float viewX, float viewY, float viewZ, float upX, float upY, float upZ) {
		pos.set(	posX,	posY,	posZ);
		view.set(	viewX,	viewY,	viewZ);
		up.set(		upX,	upY,	upZ);
	}
	
	public void look() {
		Vector3 camPos = pos.copy();
		
		if (Game.stereo) {
			Vector3 diff = view.copy().subtract(pos).cross(up).normalize2().multiply(Game.eyeDist);
			if (Game.eye == 0) //left
				camPos.subtract(diff);
			else //right
				camPos.add(diff);
		}
		Matrix.setLookAtM(Game.viewMatrix, 0, camPos.x, camPos.y, camPos.z, view.x, view.y, view.z, up.x, up.y, up.z);
	}
	
	public void moveTo(Vector3 point, float maxDist) {
		float dist = pos.distFrom(point), newDist = 0f;
		if (dist > maxDist) { //The cam can only be so far from the point
			newDist = maxDist;
			//if (shake) isShaking = true;
		} else {
			newDist = dist * Camera.MOVE_RATIO;
			//if (shake) isShaking = false;
		}
		
		//Distance from cam x,z to point x, z
		Vector3 diff = pos.copy().subtract(point);
		//Angle between cam and point
		float a = (float)atan2(diff.x, diff.z);
		
		//Find the hypotenuse of the ground-level (x, z) distance
		float hyp = (float)sqrt(diff.x*diff.x + diff.z*diff.z); //TODO: global dist function
		//Now find the angle between the hypotenuse and the y difference
		float yAng = (float)atan2(diff.y, hyp);
		
		//Set the cam pos relative to (point+newer limited following distance)
		pos.x = (float)(point.x + newDist * sin(a) * cos(yAng));
		pos.z = (float)(point.z + newDist * cos(a) * cos(yAng));
		pos.y = (float)(point.y + newDist * sin(yAng));
	}
}
